package com.example.basic.web.service.dataCode.impl;

import com.aliyuncs.utils.StringUtils;
import com.example.basic.base.impl.BaseEntityServiceImpl;
import com.example.basic.core.result.Result;
import com.example.basic.core.result.ResultGenerator;
import com.example.basic.exception.ServiceException;
import com.example.basic.web.mapper.dataCode.DataCodeMapper;
import com.example.basic.web.model.dataCode.DataCode;
import com.example.basic.web.service.common.CommonService;
import com.example.basic.web.service.dataCode.DataCodeService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import static com.example.basic.utils.CheckUtil.notNull;


/**
 * <p>
 * 系统数据代码表 服务实现类
 * </p>
 *
 * @author FanJq
 * @since 2023-09-19
 */
@Service
@Transactional
public class DataCodeServiceImpl extends BaseEntityServiceImpl<DataCodeMapper, DataCode> implements DataCodeService {

    @Resource
    private CommonService commonService;

    @Resource
    private DataCodeMapper dataCodeMapper;

    /**
     * @Description
     * 新增系统代码
     * @param params
     */
    @Override
    public DataCode saveDataCode(DataCode params) {
        notNull(params.getDataCodeName(),"代码名称不能为空");
        notNull(params.getDataCodeLen(),"代码长度不能为空");
        notNull(params.getMaxDataCodeNo(),"获取当前最大代码不能为空");

        if(params.getDataCodeNo() == null){
            params.setDataCodeNo(1L);
        }
        DataCode queryModel = new DataCode();
        queryModel.setDataCodeName(params.getDataCodeName());
        DataCode selectOne = this.selectOne(queryModel);
        if(selectOne != null){
           throw new ServiceException("代码名称已存在!");
        }

        if(StringUtils.isEmpty(params.getId())){
            preCreate(params);
        }else {
            preUpdate(params);
        }

        this.save(params);
        return params;
    }

    /**
     * @Description
     * 根据代码名称生成最大的系统代码
     * @date 2023/9/19 15:37
     * @author FanJq
     * @param dataCodeName
     * @return {@link String}
     */
    @Override
    public String generateDataCodeNo(String dataCodeName) {
        notNull(dataCodeName,"代码名称不能为空");

        DataCode queryModel = new DataCode();
        queryModel.setDataCodeName(dataCodeName);
        DataCode sysDataCode = this.selectOne(queryModel);
        if(sysDataCode == null){
            throw new ServiceException("未查询到对应的代码名称");
        }
        // 获取最大系统代码字段sql语句
        String sql = sysDataCode.getMaxDataCodeNo();
        if(sql == null || "".equals(sql)){
            throw new ServiceException("获取最大系统代码字段配置未维护，请联系管理员");
        }

        // 通过sql查询最大的系统代码
        Long maxNum = this.mapper.getMaxDataCodeNo(sql);
        if(maxNum != null){
            sysDataCode.setDataCodeNo(maxNum);
        }
        // 设置系统代码的值
        sysDataCode.setDataCodeNo(sysDataCode.getDataCodeNo() + 1);

        //特殊要求， 生成代码不得包含4
        String resultNum = "";
        if(sysDataCode.getDataCodeNo() != null){
            for (char c : String.valueOf(sysDataCode.getDataCodeNo()).toCharArray()) {
                if(String.valueOf(c).equals("4")){
                    resultNum+=Integer.valueOf(String.valueOf(c))+1;
                }else {
                    resultNum+=c;
                }
            }
            sysDataCode.setDataCodeNo(Long.valueOf(resultNum));
        }

        // 拼接处理返回最大的系统代码
        String maxDataCode = handleDataCodeValue(sysDataCode);
        return maxDataCode;
    }

    @Override
    public List<String> generateDataCodeNoList(String dataCodeName, Integer count) {
        notNull(dataCodeName,"代码名称不能为空");

        DataCode selectOne = new DataCode();
        selectOne.setDataCodeName(dataCodeName);
        DataCode sysDataCode = this.selectOne(selectOne);
        if(sysDataCode == null){
            throw new ServiceException("未查询到对应的代码名称");
        }
        // 获取最大系统代码字段sql语句
        String sql = sysDataCode.getMaxDataCodeNo();
        if(sql == null || "".equals(sql)){
            throw new ServiceException("获取最大系统代码字段配置未维护，请联系管理员");
        }

        // 通过sql查询最大的系统代码
        Long maxNum = this.mapper.getMaxDataCodeNo(sql);
        if(maxNum != null){
            sysDataCode.setDataCodeNo(maxNum+1);
        }
        // 需要进行代码生成的数据列表
        List<DataCode> resultVlueList = new ArrayList<>(count);

        // 最终返回的生成的代码数据列表
        List<String> result = new ArrayList<>();

        // 循环增加处理需要生成的数据列表
        for (int i =0; i <count; i++){
            DataCode newSysDataCode = new DataCode();
            BeanUtils.copyProperties(sysDataCode,newSysDataCode);

            //特殊要求， 生成代码不得包含4
            String resultNum = "";
            if(newSysDataCode.getDataCodeNo() != null){
                for (char c : String.valueOf(newSysDataCode.getDataCodeNo()).toCharArray()) {
                    if(String.valueOf(c).equals("4")){
                        resultNum+=Integer.valueOf(String.valueOf(c))+1;
                    }else {
                        resultNum+=c;
                    }
                }

                newSysDataCode.setDataCodeNo(Long.valueOf(resultNum));
                sysDataCode.setDataCodeNo(newSysDataCode.getDataCodeNo()+1L);

            }
            resultVlueList.add(newSysDataCode);
        }

        // 需要处理的代码数据列表不为空
        if(resultVlueList != null && resultVlueList.size() > 0){
            for (DataCode sysDataCode1 : resultVlueList) {
                // 拼接处理返回最大的系统代码
                result.add(handleDataCodeValue(sysDataCode1));
            }
        }
        return result ;
    }

    /**
     * @Description
     * 拼接处理最大的系统代码
     * @date 2023/9/19 15:42
     * @author FanJq
     * @param dataCode 系统数据代码
     * @return {@link String}
     */
    public String handleDataCodeValue(DataCode dataCode) {

        // 代码前缀-字符
        String dataCodeHead = dataCode.getDataCodeHead();
        // 当前代码长度
        Long dataCodeLen = dataCode.getDataCodeLen();
        // 当前代码
        Long DataCodeNo = dataCode.getDataCodeNo();
        // 代码前缀-年份
        String dataCodeYear = dataCode.getDataCodeYear();
        // 代码前缀年份格式
        String dataCodeYearFormat = dataCode.getDataCodeYearFormat();

        // 对系统代码前缀进行处理
        String yearPrefix = "1";
        if (yearPrefix.equals(dataCodeYear)) {
            dataCodeHead = new SimpleDateFormat(dataCodeYearFormat).format(new Date());
        }

        // 对长度不够的系统代码进行拼接0处理
        Long iZeroSize = 0L;
        if (dataCodeHead != null) {
            iZeroSize = dataCodeLen - dataCodeHead.length() - DataCodeNo.toString().length();
        } else {
            iZeroSize = dataCodeLen - DataCodeNo.toString().length();
        }
        if (iZeroSize < 0) {
            throw new ServiceException("数据长度超出指定长度!");
        }
        // 用来装载拼接了多少个 0
        StringBuffer zeroSize = new StringBuffer();
        // 循环拼接字符串
        for (int i = 0; i < iZeroSize.intValue(); i++) {
            zeroSize.append("0");
        }

        // 如果有前缀，则拼接上前缀返回
        if (dataCodeHead != null) {
            return dataCodeHead + zeroSize + DataCodeNo;
        }
        // 没有前缀，直接返回
        return ""+zeroSize + DataCodeNo;
    }

    /**
     * 生成编码 生成规则：年+月+日+4位流水号 zq
     * @param dataCodeName 编码名称
     * @return
     */
    @Override
    public String generateCode(String dataCodeName) {
        //格式 2309010001 年+月+日+4位流水号

        Date dataBaseTime = commonService.getDataBaseTime();
        //获取年份 eg:2023->23
        String year = String.valueOf(dataBaseTime.getYear()).substring(1);
        //获取月份 eg:1->01,月份不足两位补0
        String month = String.valueOf(dataBaseTime.getMonth() + 1);
        if (month.length() < 2) {
            month = "0" + month;
        }
        //获取天
        String day = String.valueOf(dataBaseTime.getDate());
        if (day.length() < 2) {
            day = "0" + day;
        }

        DataCode selectOne = new DataCode();
        selectOne.setDataCodeName(dataCodeName);
        DataCode sysDataCode = this.selectOne(selectOne);
        if (sysDataCode == null) {
           throw new ServiceException("未查询到对应的代码名称");
        }
        // 获取最大系统代码字段sql语句
        String sql = sysDataCode.getMaxDataCodeNo();
        if (sql == null || "".equals(sql)) {
            throw new ServiceException("获取最大系统代码字段配置未维护，请联系管理员");
        }

        // 通过sql查询最大的系统代码
        Long maxNum = dataCodeMapper.getMaxDataCodeNo(sql);
        if (maxNum != null) {
            sysDataCode.setDataCodeNo(maxNum);
        }

        String code = sysDataCode.getDataCodeNo().toString();

        if (code == null) {
            code = "0001";
        } else {
            //code不满十位,补0至10位
            while (code.length() < 10) {
                code = "0" + code;
            }
            //判断是否与code中的年份，月份,天相同
            if (year.equals(code.substring(0, 2)) && month.equals(code.substring(2, 4)) && day.equals(code.substring(4, 6))) {
                //相同则流水号加1
                code = String.valueOf(Long.parseLong(code) + 1);
            } else {
                //不同则流水号从1开始
                code =year + month +day+ "0001";
            }
        }
        return  code;
    }
}